package cn.hill4j.spring.std.aop.proxy;

import org.springframework.cglib.core.ClassLoaderAwareGeneratorStrategy;
import org.springframework.cglib.core.SpringNamingPolicy;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.MethodInterceptor;

public class EnhancerDemo {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        ClassLoader classLoader = EnhancerDemo.class.getClassLoader();
        enhancer.setClassLoader(classLoader);


        enhancer.setSuperclass(Target.class);
        enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
        enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));

        Callback[] callbacks = new Callback[]{
                (MethodInterceptor) (o, method, objects,methodProxy) -> {
                    try{
                        System.out.println("before1");
                        Object rst = methodProxy.invokeSuper(o,objects);
                        System.out.println("succ end1");
                        return rst;
                    }catch (Exception e){
                        System.out.println("Exception1:"+e.getStackTrace());
                        throw e;
                    }finally {
                        System.out.println("end1");
                    }
                },(InvocationHandler) (o, method, objects) -> {
            try{
                System.out.println("before");
                Object rst = method.invoke(o,objects);
                System.out.println("succ end");
                return rst;
            }catch (Exception e){
                System.out.println("Exception:"+e.getStackTrace());
                throw e;
            }finally {
                System.out.println("end");
            }
        }
        };
        enhancer.setCallbacks(callbacks);
        Class<?>[] types = new Class<?>[callbacks.length];
        for (int x = 0; x < types.length; x++) {
            types[x] = callbacks[x].getClass();
        }
        // fixedInterceptorMap only populated at this point, after getCallbacks call above
        /*enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(
                this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));*/
        Target proxy = (Target) enhancer.create();
        proxy.exeTarget();
    }
}
